package com.yanqu.road.server.manager.tomb;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.yanqu.road.pb.tomb.Tomb;
import com.yanqu.road.server.manager.activity.seacraftsouthsea.SeacraftSouthSeaConfigMgr;
import com.yanqu.road.server.manager.tomb.astar.AStar;
import com.yanqu.road.server.manager.tomb.astar.Coordinate;
import com.yanqu.road.server.manager.tomb.astar.Node;
import com.yanqu.road.server.manager.tomb.entity.DoorInfo;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.*;

public class Maze {

    private static Logger logger = LogManager.getLogger(Maze.class.getName());

    private int maxRow;
    private int maxColumn;

    private int doorNum;

    private int bigGripLimit;

    private int totalBigEventNum;

    private int totalNormalEventNum;
    private int buffEventNum = 0;
    private int maxStep = 2;

    private Map<Integer, DoorInfo> doorInfoMap = new HashMap<>();

    private List<Coordinate> buffEventList = new ArrayList<>();
    private String[][] sGrip;

    @JsonIgnore
    private Map<Integer, List<Position>> surplusBigBoxMap = new HashMap<>();
    @JsonIgnore
    private Map<Integer, List<Position>> bigBoxMap = new LinkedHashMap<>();

    @JsonIgnore
    private Map<String, Coordinate> verifyMap = new HashMap<>();

    public Maze() {

    }

    Maze(int doorNum, int bigGripLimit, int buffEventNum, int totalBigEventNum, int totalNormalEventNum) {
        bigGripLimit = bigGripLimit + buffEventNum + totalBigEventNum;
        double sqrt = Math.sqrt(bigGripLimit);
        if (sqrt < 20) {
            sqrt = Math.ceil(sqrt);
        }
        int sqrtInt = (int) sqrt;
        int max = (int) ((double) sqrtInt * 3.6);
        int d = max % 3;
        max = max + (3 - d);
        max = max + 2;
        this.maxRow = max;
        this.maxColumn = max;
        this.doorNum = doorNum;
        this.bigGripLimit = bigGripLimit;
        this.buffEventNum = buffEventNum;

        this.totalBigEventNum = totalBigEventNum;
        this.totalNormalEventNum = totalNormalEventNum;

        this.sGrip = new String[this.maxRow][];
        for (int i = 0; i < this.sGrip.length; i++) {
            this.sGrip[i] = new String[this.maxColumn];
        }
    }


    public static Maze newMaze(int doorNum, int bigBoxLimit, int buffEventNum, int totalBigEventNum, int totalNormalEventNum) {
        return new Maze(doorNum, bigBoxLimit, buffEventNum, totalBigEventNum, totalNormalEventNum);
    }


    public void printTime() {

    }

    public boolean generate() {

        long t1 = System.currentTimeMillis();

        this.generateWall();

        this.generateDoor();

        if (!this.generateBigBox()) {
            return false;
        }


        for (List<Position> positions : this.surplusBigBoxMap.values()) {
            this.randDecorate(positions);
        }

//        this.clearUntreated();
        if (!this.generateConnect()) {
            return false;
        }


        Set<Integer> deleteSet = new HashSet<>();
        for (Map.Entry<Integer, List<Position>> listEntry : this.surplusBigBoxMap.entrySet()) {
            boolean brake = false;
            for (Position position : listEntry.getValue()) {
                Position position1 = new Position(position.getRow(), position.getColumn());
                position1.parseString(this.sGrip[position1.getRow()][position1.getColumn()]);
                if (position1.getpEnum() == Tomb.PositionEnum.POSITION_ROAD_VALUE && position1.getDecoration().equals("brake")) {
                    brake = true;
                    break;
                }
            }
            if (brake) {
                deleteSet.add(listEntry.getKey());
                for (Position position : listEntry.getValue()) {
                    Position position1 = new Position(position.getRow(), position.getColumn());
                    position1.parseString(this.sGrip[position1.getRow()][position1.getColumn()]);
                    position1.pEnum = Tomb.PositionEnum.POSITION_ROAD_VALUE;
                    position1.setDecoration("brake");
                    position1.flag = 0;
                    this.sGrip[position1.getRow()][position1.getColumn()] = position1.toString();
                }
            }
        }
        for (Integer integer : deleteSet) {
            this.surplusBigBoxMap.remove(integer);
        }
        this.surplusBigBoxMap.clear();
        this.bigBoxMap.clear();
        this.verifyMap.clear();

        return true;
    }

    private void clearUntreated() {
        for (int row = 0; row < this.sGrip.length; row++) {
            for (int column = 0; column < this.sGrip[row].length; column++) {

                String s = this.sGrip[row][column];
                Position position = new Position(row, column);
                position.parseString(s);

                if (position.getpEnum() == Tomb.PositionEnum.POSITION_NONE_VALUE) {
                    position.setpEnum(Tomb.PositionEnum.POSITION_ROAD_VALUE);
                }
                this.sGrip[row][column] = position.toString();
            }
        }
    }

    private void generateWall() {
        for (int row = 0; row < this.sGrip.length; row++) {
            for (int column = 0; column < this.sGrip[row].length; column++) {
                if (row == 0 || row == this.maxRow - 1 || column == 0 || column == this.maxColumn - 1) {
                    Position position = new Position(row, column);
                    position.setpEnum(Tomb.PositionEnum.POSITION_WALL_VALUE);
                    this.sGrip[row][column] = position.toString();
                } else {
                    Position position = new Position(row, column);
                    position.setpEnum(Tomb.PositionEnum.POSITION_NONE_VALUE);
                    this.sGrip[row][column] = position.toString();
                }
            }
        }
    }

    private void generateDoor() {
        Random random = new Random();
        int g = 3;

        int x = this.maxRow / g;

        int y = this.maxColumn / g;

        int total = x + y;
        int space = total / this.doorNum;
        int index = 0;
        int nextInt = random.nextInt(space);
        try {
            for (int i = 0; i < this.doorNum; i++) {
                int p = i * space + nextInt;
                if (p < x) {
                    Position position = new Position(this.maxRow - p * g - 2 - 1, 0);
                    position.setpEnum(Tomb.PositionEnum.POSITION_DOOR_VALUE);
                    this.sGrip[position.getRow()][position.getColumn()] = position.toString();
                    DoorInfo doorInfo = new DoorInfo();
                    doorInfo.setX(position.getRow());
                    doorInfo.setY(position.getColumn());
                    this.doorInfoMap.put(index, doorInfo);
                    index++;
                    continue;
                }
                p = p - x;
                if (p < y) {
                    Position position = new Position(0, +p * g + 2);
                    position.setpEnum(Tomb.PositionEnum.POSITION_DOOR_VALUE);
                    this.sGrip[position.getRow()][position.getColumn()] = position.toString();
                    DoorInfo doorInfo = new DoorInfo();
                    doorInfo.setX(position.getRow());
                    doorInfo.setY(position.getColumn());
                    this.doorInfoMap.put(index, doorInfo);
                    index++;
                    continue;
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        for (DoorInfo door : this.doorInfoMap.values()) {

            if (door.getX() == 0) {
                List<Position> bigBoxWith = this.getBigBoxWith(door.getX() + 2, door.getY());
                for (Position position1 : bigBoxWith) {
                    position1.setFlag(0);
                    position1.setpEnum(Tomb.PositionEnum.POSITION_ROAD_VALUE);
                    this.sGrip[position1.getRow()][position1.getColumn()] = position1.toString();
                }
            } else if (door.getY() == 0) {
                List<Position> bigBoxWith = this.getBigBoxWith(door.getX(), door.getY() + 2);
                for (Position position1 : bigBoxWith) {
                    position1.setFlag(0);
                    position1.setpEnum(Tomb.PositionEnum.POSITION_ROAD_VALUE);
                    this.sGrip[position1.getRow()][position1.getColumn()] = position1.toString();
                }
            }
        }

    }

    private boolean generateBigBox() {
        int row = this.maxRow - 4;
        int column = this.maxColumn - 4;
        Random random = new Random();
        int _row = 0;
        int _column = 0;
        int index = 0;

        int whileTimes = 0;

        while (_column < column) {
            if (whileTimes >= 50000) {
                break;
            }
            whileTimes++;

            int _nextInt = random.nextInt(this.maxStep) + 2;
            _row = _row + _nextInt;
            if (_row > row) {
                _row = 0;
                _column = _column + 1;
                continue;
            }
            List<Position> bigBoxWith = this.getBigBoxWith(_row + 2, _column + 2);
            long count = bigBoxWith.stream().filter(position -> {
                return position.getpEnum() != Tomb.PositionEnum.POSITION_NONE_VALUE;
            }).limit(1).count();
            if (count > 0) {
                continue;
            }
            for (Position position : bigBoxWith) {
                position.setpEnum(Tomb.PositionEnum.POSITION_EXPLORE_VALUE);
                position.setLockIndex(index + 1);
                this.sGrip[position.row][position.column] = position.toString();
            }
            this.bigBoxMap.put(index, bigBoxWith);
            index++;
        }
        logger.info("{}个门,地图x{},y{},生成了{}个大箱子, 限制{}个", this.doorNum, this.maxRow, this.maxColumn, this.bigBoxMap.size(), this.bigGripLimit);

        if (this.bigBoxMap.size() < this.bigGripLimit) {
            return false;
        }
        if (this.bigBoxMap.size() > this.bigGripLimit) {
            int diff = this.bigBoxMap.size() - this.bigGripLimit;
            HashSet<Integer> integerHashSet = new HashSet<>();
            int size = this.bigBoxMap.size();
            int whileTimes1 = 0;
            while (integerHashSet.size() < diff) {
                if (whileTimes1 >= 10000) {
                    break;
                }
                whileTimes1++;
                integerHashSet.add(random.nextInt(size));

            }
            for (int i : integerHashSet) {
                List<Position> list = this.bigBoxMap.get(i);
                this.surplusBigBoxMap.put(i, list);
                this.bigBoxMap.remove(i);
            }
        }

        this.totalBigEventNum = this.bigGripLimit - this.buffEventNum;
        //生成随机的BUFF事件
        HashSet<Integer> buffEventHashSet = new HashSet<>();

        int whileTimes2 = 0;

        while (buffEventHashSet.size() < this.buffEventNum) {
            if (whileTimes2 >= 10000) {
                break;
            }
            whileTimes2++;
            int i = random.nextInt(index);
            if (!this.bigBoxMap.containsKey(i)) {
                continue;
            }
            buffEventHashSet.add(i);
        }
        for (Integer integer : buffEventHashSet) {
            List<Position> positions = this.bigBoxMap.get(integer);
            Position flagPosition = null;
            for (Position position : positions) {
                if (position.getFlag() == 1) {
                    position.setpEnum(Tomb.PositionEnum.POSITION_EVENT_VALUE);
                    position.seteType(Tomb.EventEnum.EVENT_BUFF_VALUE);
                    String s = position.toString();
                    this.sGrip[position.getRow()][position.getColumn()] = s;
                    flagPosition = position;
                    Coordinate coordinate = Coordinate.newInstance(position.getRow(), position.getColumn());
                    this.buffEventList.add(coordinate);
                    break;
                }
            }
            for (Position position : positions) {
                if (position.getFlag() == 1) {
                    continue;
                }
                position.setpEnum(Tomb.PositionEnum.POSITION_ROAD_VALUE);
                position.setpRelation(flagPosition.getKey());
                String s = position.toString();
                this.sGrip[position.getRow()][position.getColumn()] = s;
            }
            this.bigBoxMap.remove(integer);
        }

        int i1 = this.totalNormalEventNum % 9;
        if (i1 > 0) {
            this.totalBigEventNum = this.totalBigEventNum - 1;
            ArrayList<List<Position>> lists = new ArrayList<>(this.bigBoxMap.values());
            Random random1 = new Random();
            int i = random1.nextInt(lists.size());
            List<Position> positions = lists.get(i);
            for (Position position : positions) {
                if (position.getFlag() == 1) {
                    position.setFlag(0);
                }
                position.setDecoration("d");
                position.setpRelation("");
                if (i1 == 0) {
                    String s = position.toString();
                    this.sGrip[position.getRow()][position.getColumn()] = s;
                    continue;
                }
                position.setpEnum(Tomb.PositionEnum.POSITION_ROAD_VALUE);
                String s = position.toString();
                this.sGrip[position.getRow()][position.getColumn()] = s;
                i1--;
            }
        }
        return true;
    }

    private List<Position> getBigBoxWith(int startX, int startY) {
        List<Position> list = new ArrayList<>();
        Position pf = null;
        for (int i = -1; i < 2; i++) {
            for (int j = -1; j < 2; j++) {
                Position p1 = new Position(startX + i, startY + j);
                list.add(p1);
                if (i == 1 && j == 1) {
                    p1.setFlag(1);
                    pf = p1;
                }
            }
        }
        try {
            for (Position position : list) {
                position.parseString(this.sGrip[position.getRow()][position.getColumn()]);
                if (position.getFlag() == 1) {
                    continue;
                }
                position.setpRelation(pf.getKey());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


        return list;
    }


    private boolean generateConnect() {
        int randomRow = this.maxRow / 2;
        int randomColumn = this.maxColumn / 2;
        Coordinate center = Coordinate.newInstance(randomRow, randomColumn);


        List<Coordinate> startCoordinateList = new ArrayList<>();
        for (DoorInfo doorInfo : this.doorInfoMap.values()) {
            Coordinate coordinate = new Coordinate();
            coordinate.setX(doorInfo.getX());
            coordinate.setY(doorInfo.getY());
            startCoordinateList.add(coordinate);
        }

        startCoordinateList.addAll(this.buffEventList);

        for (List<Position> positionList : this.bigBoxMap.values()) {
            Coordinate coordinate = new Coordinate();
            Position position = positionList.get(0);
            coordinate.setX(position.getRow());
            coordinate.setY(position.getColumn());
            startCoordinateList.add(coordinate);
        }

        int canNotFindPathCount = 0;
        for (Coordinate coordinate1 : startCoordinateList) {
            int _row = coordinate1.getX();
            int _column = coordinate1.getY();
            Coordinate start = Coordinate.newInstance(_row, _column);


            int minDistance = AStar.getToEndDistance(start, center);
            Coordinate minCoordinate = center;
            for (Coordinate value : this.verifyMap.values()) {
                int distance = AStar.getToEndDistance(start, value);
                if (distance < minDistance) {
                    minCoordinate = value;
                    minDistance = distance;
                }
            }

            Coordinate end = minCoordinate;
            Map<String, Node> m_openMap = new HashMap<>();
            Map<String, Node> m_closeMap = new HashMap<>();
            Node m_endNode = null;

            Node startCode = new Node(start, null, 0, 0);
            m_openMap.put(startCode.getCoordinate().getKey(), startCode);

            int whileTimes = 0;
            while (m_openMap.size() > 0 && m_endNode == null) {
                if (whileTimes >= 100000) {
                    break;
                }
                whileTimes++;
                ArrayList<Node> nodes = new ArrayList<>(m_openMap.values());
                nodes.sort(Comparator.comparing(Node::getM_f));
                Node node = nodes.get(0);
                m_openMap.remove(node.getCoordinate().getKey());
                for (int i = -1; i < 2; i++) {
                    for (int j = -1; j < 2; j++) {
                        if (Math.abs(i) == Math.abs(j)) {
                            continue;
                        }
                        int x = node.getCoordinate().getX() + i;
                        int y = node.getCoordinate().getY() + j;
                        Coordinate _coordinate = Coordinate.newInstance(x, y);
                        if (m_closeMap.containsKey(_coordinate.getKey())) {
                            continue;
                        }
                        if (x == -1 || y == -1) {
                            continue;
                        }
                        Position position = new Position(x, y);
                        position.parseString(this.sGrip[x][y]);
                        if (!position.canExploreThrough()) {
                            if (!_coordinate.equals(end)) {
                                continue;
                            }
                        }
                        int node_g = node.getM_g() + 1;
                        if (m_openMap.containsKey(_coordinate.getKey())) {
                            if (node_g < m_openMap.get(_coordinate.getKey()).getM_g()) {
                                m_openMap.get(_coordinate.getKey()).setM_g(node_g);
                                m_openMap.get(_coordinate.getKey()).setParent(node);
                            }
                        } else {
                            int a = Math.abs(_coordinate.getX() - end.getX());
                            int b = Math.abs(_coordinate.getY() - end.getY());
                            int h = a + b;
                            Node _node = new Node(_coordinate, node, node_g, h);
                            if (_coordinate.equals(end)) {
                                m_endNode = _node;
                            } else {
                                m_openMap.put(_node.getCoordinate().getKey(), _node);
                            }
                        }
                    }
                }

                m_closeMap.put(node.getCoordinate().getKey(), node);
            }
            boolean pass = false;

            if (m_endNode != null) {
                pass = true;
            }


//            long t9 = System.currentTimeMillis();
//            seconds = t9 - t8;
//            logger.info("t8相差时间 {}", seconds);

            if (pass) {
                this.verifyMap.put(start.getKey(), start);
                continue;
            }
            canNotFindPathCount++;
            if (canNotFindPathCount > 100) {
                return false;
            }
            int count = 0;
            boolean leftRight = false;
            while (_row != randomRow || _column != randomColumn) {
                count++;
                if (count > 1000) {
                    return false;
                }
                try {
                    if (leftRight) {
                        if (_row != randomRow) {
                            int raw_row = _row;
                            if (_row < randomRow) {
                                _row++;
                            } else {
                                _row--;
                            }
                            Position rp = new Position(_row, _column);
                            rp.parseString(this.sGrip[rp.getRow()][rp.getColumn()]);
                            if (rp.getpEnum() == Tomb.PositionEnum.POSITION_WALL_VALUE) {
                                _row = raw_row;
                            }
                        }
                    } else {
                        if (_column != randomColumn) {
                            int raw_column = _column;
                            if (_column < randomColumn) {
                                _column++;
                            } else {
                                _column--;
                            }
                            Position rp = new Position(_row, _column);
                            rp.parseString(this.sGrip[rp.getRow()][rp.getColumn()]);
                            if (rp.getpEnum() == Tomb.PositionEnum.POSITION_WALL_VALUE) {
                                _column = raw_column;
                            }
                        }
                    }
                    Position rp = new Position(_row, _column);
                    rp.parseString(this.sGrip[rp.getRow()][rp.getColumn()]);
                    if (rp.getpEnum() == Tomb.PositionEnum.POSITION_NONE_VALUE || rp.getpEnum() == Tomb.PositionEnum.POSITION_DECORATION_VALUE) {
                        rp.setpEnum(Tomb.PositionEnum.POSITION_ROAD_VALUE);
                        rp.setDecoration("brake");
                        this.sGrip[_row][_column] = rp.toString();
                    }
                } finally {
                    leftRight = !leftRight;
                }
            }
            this.verifyMap.put(start.getKey(), start);

        }
        return true;
    }

    public void updatePosition(Position position) {
        this.sGrip[position.getRow()][position.getColumn()] = position.toString();
    }


    public int getMaxRow() {
        return maxRow;
    }

    public void setMaxRow(int maxRow) {
        this.maxRow = maxRow;
    }

    public int getMaxColumn() {
        return maxColumn;
    }

    public void setMaxColumn(int maxColumn) {
        this.maxColumn = maxColumn;
    }

    public int getDoorNum() {
        return doorNum;
    }

    public void setDoorNum(int doorNum) {
        this.doorNum = doorNum;
    }

    public int getBigGripLimit() {
        return bigGripLimit;
    }

    public void setBigGripLimit(int bigGripLimit) {
        this.bigGripLimit = bigGripLimit;
    }

    public int getMaxStep() {
        return maxStep;
    }

    public void setMaxStep(int maxStep) {
        this.maxStep = maxStep;
    }


    public String[][] getsGrip() {
        return sGrip;
    }


    public Map<Integer, DoorInfo> getDoorInfoMap() {
        return doorInfoMap;
    }

    public void setDoorInfoMap(Map<Integer, DoorInfo> doorInfoMap) {
        this.doorInfoMap = doorInfoMap;
    }

    public DoorInfo acquireDoorInfo(String s) {
        for (DoorInfo doorInfo : this.doorInfoMap.values()) {
            if (doorInfo.getUnionSet().contains(s)) {
                return doorInfo;
            }
        }
        ArrayList<DoorInfo> doorInfos = new ArrayList<>(this.doorInfoMap.values());
        doorInfos.sort(Comparator.comparing(DoorInfo::acquireUnionNum));
        DoorInfo doorInfo = doorInfos.get(0);
        doorInfo.getUnionSet().add(s);
        return doorInfo;
    }

    /**
     * 调试方法，打印出格子当前的状态
     * @return
     */
    public int[][] generateIntGrip() {
        String[][] sGrip = this.sGrip;
        int[][] grip = new int[sGrip.length][];
        for (int i = 0; i < sGrip.length; i++) {
            grip[i] = new int[sGrip[i].length];
            for (int i1 = 0; i1 < sGrip[i].length; i1++) {
                String s = sGrip[i][i1];
                Position position = new Position(i, i1);
                position.parseString(s);
                if (position.canExploreThrough()) {
                    grip[i][i1] = 0;
                } else {
                    grip[i][i1] = 1;
                }
            }
        }
        return grip;
    }

    public int getTotalBigEventNum() {
        return totalBigEventNum;
    }

    public int getTotalNormalEventNum() {
        return totalNormalEventNum;
    }

    public int getBuffEventNum() {
        return buffEventNum;
    }

    public void randDecorate(List<Position> list) {
        String[][] a1 = {
                {"", "", "r"},
                {"", "5", "r"},
                {"r", "r", "6"}
        };
        String[][] a2 = {
                {"r", "", ""},
                {"r", "", "5"},
                {"6", "r", "r"}
        };
        String[][] a3 = {
                {"7", "r", "7"},
                {"r", "r", "r"},
                {"7", "r", "7"}
        };
        String[][] a4 = {
                {"r", "w6", "w6"},
                {"r", "", ""},
                {"r", "", "4"}
        };
        String[][] a5 = {
                {"", "", "r"},
                {"", "4", "r"},
                {"w6", "w6", "r"}
        };
        String[][] a6 = {
                {"", "", "w6"},
                {"", "9", "w6"},
                {"w6", "w6", "w6"}
        };
        String[][] a7 = {
                {"", "", "w6"},
                {"", "8", "w6"},
                {"w6", "w6", "r"}
        };
        String[][] a8 = {
                {"", "", "r"},
                {"", "8", "w6"},
                {"w6", "w6", "r"}
        };
        String[][] a9 = {
                {"2", "r", "r"},
                {"r", "", ""},
                {"r", "", "9"}
        };
        String[][] a10 = {
                {"", "", ""},
                {"", "", ""},
                {"", "", "1"}
        };
        String[][] a11 = {
                {"r", "r", "r"},
                {"3", "r", "3"},
                {"r", "r", "r"}
        };
        String[][] a12 = {
                {"w6", "w6", "w6"},
                {"3", "w6", "3"},
                {"r", "r", "r"}
        };
        String[][] a13 = {
                {"w6", "r", "w6"},
                {"3", "r", "3"},
                {"r", "r", "r"}
        };
        String[][] a14 = {
                {"r", "", ""},
                {"r", "", "8"},
                {"2", "w6", "w6"}
        };
        String[][] a15 = {
                {"r", "r", "r"},
                {"", "", "r"},
                {"", "8", "2"}
        };
        String[][] a16 = {
                {"r", "r", "r"},
                {"", "", "r"},
                {"", "9", "r"}
        };
        String[][] a17 = {
                {"r", "", ""},
                {"r", "", "9"},
                {"r", "r", "r"}
        };
        String[][] a18 = {
                {"", "", "r"},
                {"", "4", "r"},
                {"r", "r", "r"}
        };
        String[][] a19 = {
                {"r", "", ""},
                {"r", "", "4"},
                {"r", "r", "r"}
        };
        String[][] a20 = {
                {"r", "r", "r"},
                {"r", "", ""},
                {"r", "", "4"}
        };
        String[][] a21 = {
                {"r", "r", "r"},
                {"", "", "r"},
                {"", "4", "r"}
        };
        String[][] a22 = {
                {"", "", "r"},
                {"", "4", "r"},
                {"r", "2", "r"}
        };
        String[][] a23 = {
                {"", "", "r"},
                {"", "4", "2"},
                {"r", "r", "r"}
        };
        String[][] a24 = {
                {"w6", "r", "w6"},
                {"3", "r", "3"},
                {"r", "r", "r"}
        };
        String[][] a25 = {
                {"r", "r", "r"},
                {"w6", "w6", "w6"},
                {"r", "r", "r"}
        };
        String[][] a26 = {
                {"r", "w6", "r"},
                {"r", "w6", "r"},
                {"r", "w6", "r"}
        };
        String[][] a27 = {
                {"w6", "r", "w6"},
                {"3", "r", "3"},
                {"r", "r", "r"}
        };
        String[][] a28 = {
                {"r", "w6", "w6"},
                {"r", "r", "w6"},
                {"r", "w6", "r"}
        };
        String[][] a29 = {
                {"2", "r", "w6"},
                {"r", "r", "w6"},
                {"r", "w6", "r"}
        };
        String[][] a30 = {
                {"r", "w6", "w6"},
                {"r", "r", "w6"},
                {"3", "r", "r"}
        };

        String[][][] a = {a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
                a11, a12, a13, a14, a15, a16, a17, a18, a19, a20,
                a21, a22, a23, a24, a25, a26, a27, a28, a29, a30};

        Random random = new Random();
        int i = random.nextInt(a.length);
        String[][] d = a[i];

        int x = 0;
        int y = 0;

        for (Position position : list) {
            if (position.getFlag() == 1) {
                x = position.getRow() - 2;
                y = position.getColumn() - 2;
            }
        }

        if (x == 0 && y == 0) {
            return;
        }


        for (int i1 = 0; i1 < d.length; i1++) {
            for (int i2 = 0; i2 < d[i1].length; i2++) {
                String s = this.sGrip[x + i1][y + i2];

                for (Position position : list) {
                    if (position.getRow() == x + i1 && position.getColumn() == y + i2) {
                        position.setFlag(0);
                        String s1 = d[i1][i2];
                        position.setDecoration(s1);
                        if (s1.equals("r")) {
                            position.setpEnum(Tomb.PositionEnum.POSITION_ROAD_VALUE);
                        } else {
                            position.setpEnum(Tomb.PositionEnum.POSITION_DECORATION_VALUE);
                            position.setpRelation("");
                        }
                        this.sGrip[x + i1][y + i2] = position.toString();
                        break;
                    }
                }

            }
        }
    }


}
